﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Xsl;
using log4net;
using MPMovieCatalog.Domain;

namespace MPMovieCatalog.Util
{
    public class Utils
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(Utils));

        private static List<string> tempFiles = new List<string>();

        public static string TransformMovie(MovieInfo movieInfo)
        {
            StringWriter result = new StringWriter();
            if (movieInfo != null)
            {
                if (movieInfo.Picture != null && movieInfo.Picture != string.Empty)
                {
                    movieInfo.PictureFileName = GetTempFileName();
                    File.WriteAllBytes(movieInfo.PictureFileName, Convert.FromBase64String(movieInfo.Picture));
                }

                StringWriter sw = new StringWriter();

                XslCompiledTransform xslt = new XslCompiledTransform();
                xslt.Load(Application.StartupPath + @"\templates\view_item_details_aqua2.xsl");

                XmlDocument movieXml = movieInfo.ToXML();
                XmlElement metadataXml = movieXml.CreateElement("metadata");
                movieXml.DocumentElement.AppendChild(metadataXml);

                Dictionary<string, string> metadata = ResourceUtils.GetSection("template");
                foreach (string name in metadata.Keys)
                {
                    XmlElement element = movieXml.CreateElement("field");

                    XmlAttribute nameAttr = movieXml.CreateAttribute("name");
                    nameAttr.Value = name;

                    XmlAttribute labelAttr = movieXml.CreateAttribute("label");
                    labelAttr.Value = metadata[name];

                    element.Attributes.Append(nameAttr);
                    element.Attributes.Append(labelAttr);

                    metadataXml.AppendChild(element);
                }

                xslt.Transform(new XmlNodeReader(movieXml), new XmlTextWriter(sw));

                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.LoadXml(sw.ToString());

                XmlNode headNode = xmlDocument.SelectSingleNode("//HEAD");
                if (headNode == null)
                {
                    headNode = xmlDocument.CreateElement("HEAD");
                    xmlDocument.DocumentElement.AppendChild(headNode);
                }

                XmlNode baseNode = headNode.SelectSingleNode("//BASE");
                if (baseNode == null)
                {
                    baseNode = xmlDocument.CreateElement("BASE");
                    ((XmlElement)baseNode).SetAttribute("href", Application.StartupPath + @"\templates\");
                    headNode.PrependChild(baseNode);
                }

                xmlDocument.WriteTo(new XmlTextWriter(result));
            }

            return result.ToString();

        }

        public static string DownloadImage(string url)
        {
            string fileName = GetTempFileName();
            if (!string.IsNullOrEmpty(url))
            {
                try
                {
                    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
                    webRequest.Timeout = 5000;
                    HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

                    using (Stream stream = webResponse.GetResponseStream())
                    {
                        byte[] inBuf = new byte[900000];
                        int bytesToRead = (int)inBuf.Length;
                        int bytesRead = 0;

                        DateTime dt = DateTime.Now;
                        while (bytesToRead > 0)
                        {
                            dt = DateTime.Now;
                            int n = stream.Read(inBuf, bytesRead, bytesToRead);
                            if (n == 0)
                                break;
                            bytesRead += n;
                            bytesToRead -= n;
                            TimeSpan ts = DateTime.Now - dt;
                            if (ts.TotalSeconds >= 5)
                            {
                                throw new System.Exception("timeout");
                            }
                        }
                        using (FileStream fileStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
                        {
                            fileStream.Write(inBuf, 0, bytesRead);
                            stream.Close();
                            fileStream.Close();
                        }
                    }

                }
                catch (System.Exception ex)
                {
                    log.Error(string.Format("Error downloading image from \"{0}\" to file \"{1}\"", url, fileName), ex);
                }
            }
            return fileName;
        }

        public static string GetTempFileName()
        {
            string fileName = Path.GetTempFileName();
            tempFiles.Add(fileName);

            return fileName;
        }

        public static void DeleteTempFiles()
        {
            foreach (string fileName in tempFiles)
            {
                try
                {
                    File.Delete(fileName);
                }
                catch (System.Exception ex)
                {
                    log.Error(string.Format("Error deleting file {0}", fileName), ex);
                }
            }
        }
    }
}
